# -*- coding: utf-8 -*-
"""
Redis API接口
提供Redis操作的示例接口
"""

from fastapi import APIRouter, HTTPException, Depends
from pydantic import BaseModel
from typing import Optional, Dict, Any

from src.cores.redis import get_redis, RedisManager
from src.utils.logger import app_logger as logger

router = APIRouter()


class CacheItem(BaseModel):
    """缓存项模型"""
    key: str
    value: str
    expire: Optional[int] = None  # 过期时间（秒）


class CacheResponse(BaseModel):
    """缓存响应模型"""
    success: bool
    message: str
    data: Optional[Any] = None


@router.post("/cache", response_model=CacheResponse, summary="设置缓存")
async def set_cache(
    item: CacheItem,
    redis: RedisManager = Depends(get_redis)
) -> CacheResponse:
    """设置缓存数据"""
    try:
        success = await redis.set(item.key, item.value, ex=item.expire)
        if success:
            logger.info(f"缓存设置成功: {item.key}")
            return CacheResponse(
                success=True,
                message="缓存设置成功",
                data={"key": item.key, "expire": item.expire}
            )
        else:
            raise HTTPException(status_code=500, detail="缓存设置失败")
    except Exception as e:
        logger.error(f"设置缓存失败: {e}")
        raise HTTPException(status_code=500, detail=f"设置缓存失败: {str(e)}")


@router.get("/cache/{key}", response_model=CacheResponse, summary="获取缓存")
async def get_cache(
    key: str,
    redis: RedisManager = Depends(get_redis)
) -> CacheResponse:
    """获取缓存数据"""
    try:
        value = await redis.get(key)
        if value is not None:
            logger.info(f"缓存获取成功: {key}")
            return CacheResponse(
                success=True,
                message="缓存获取成功",
                data={"key": key, "value": value}
            )
        else:
            return CacheResponse(
                success=False,
                message="缓存不存在或已过期",
                data=None
            )
    except Exception as e:
        logger.error(f"获取缓存失败: {e}")
        raise HTTPException(status_code=500, detail=f"获取缓存失败: {str(e)}")


@router.delete("/cache/{key}", response_model=CacheResponse, summary="删除缓存")
async def delete_cache(
    key: str,
    redis: RedisManager = Depends(get_redis)
) -> CacheResponse:
    """删除缓存数据"""
    try:
        deleted_count = await redis.delete(key)
        if deleted_count > 0:
            logger.info(f"缓存删除成功: {key}")
            return CacheResponse(
                success=True,
                message="缓存删除成功",
                data={"key": key, "deleted_count": deleted_count}
            )
        else:
            return CacheResponse(
                success=False,
                message="缓存不存在",
                data={"key": key, "deleted_count": 0}
            )
    except Exception as e:
        logger.error(f"删除缓存失败: {e}")
        raise HTTPException(status_code=500, detail=f"删除缓存失败: {str(e)}")


@router.get("/cache/{key}/exists", response_model=CacheResponse, summary="检查缓存是否存在")
async def check_cache_exists(
    key: str,
    redis: RedisManager = Depends(get_redis)
) -> CacheResponse:
    """检查缓存是否存在"""
    try:
        exists = await redis.exists(key)
        return CacheResponse(
            success=True,
            message="检查完成",
            data={"key": key, "exists": exists}
        )
    except Exception as e:
        logger.error(f"检查缓存失败: {e}")
        raise HTTPException(status_code=500, detail=f"检查缓存失败: {str(e)}")


@router.post("/counter/{key}/incr", response_model=CacheResponse, summary="递增计数器")
async def increment_counter(
    key: str,
    amount: int = 1,
    redis: RedisManager = Depends(get_redis)
) -> CacheResponse:
    """递增计数器"""
    try:
        new_value = await redis.incr(key, amount)
        logger.info(f"计数器递增成功: {key} = {new_value}")
        return CacheResponse(
            success=True,
            message="计数器递增成功",
            data={"key": key, "value": new_value, "increment": amount}
        )
    except Exception as e:
        logger.error(f"计数器递增失败: {e}")
        raise HTTPException(status_code=500, detail=f"计数器递增失败: {str(e)}")


@router.post("/counter/{key}/decr", response_model=CacheResponse, summary="递减计数器")
async def decrement_counter(
    key: str,
    amount: int = 1,
    redis: RedisManager = Depends(get_redis)
) -> CacheResponse:
    """递减计数器"""
    try:
        new_value = await redis.decr(key, amount)
        logger.info(f"计数器递减成功: {key} = {new_value}")
        return CacheResponse(
            success=True,
            message="计数器递减成功",
            data={"key": key, "value": new_value, "decrement": amount}
        )
    except Exception as e:
        logger.error(f"计数器递减失败: {e}")
        raise HTTPException(status_code=500, detail=f"计数器递减失败: {str(e)}")


class HashItem(BaseModel):
    """哈希表项模型"""
    name: str
    key: str
    value: str


@router.post("/hash", response_model=CacheResponse, summary="设置哈希表字段")
async def set_hash_field(
    item: HashItem,
    redis: RedisManager = Depends(get_redis)
) -> CacheResponse:
    """设置哈希表字段"""
    try:
        result = await redis.hset(item.name, item.key, item.value)
        logger.info(f"哈希表字段设置成功: {item.name}.{item.key}")
        return CacheResponse(
            success=True,
            message="哈希表字段设置成功",
            data={"name": item.name, "key": item.key, "result": result}
        )
    except Exception as e:
        logger.error(f"设置哈希表字段失败: {e}")
        raise HTTPException(status_code=500, detail=f"设置哈希表字段失败: {str(e)}")


@router.get("/hash/{name}/{key}", response_model=CacheResponse, summary="获取哈希表字段")
async def get_hash_field(
    name: str,
    key: str,
    redis: RedisManager = Depends(get_redis)
) -> CacheResponse:
    """获取哈希表字段"""
    try:
        value = await redis.hget(name, key)
        if value is not None:
            return CacheResponse(
                success=True,
                message="哈希表字段获取成功",
                data={"name": name, "key": key, "value": value}
            )
        else:
            return CacheResponse(
                success=False,
                message="哈希表字段不存在",
                data=None
            )
    except Exception as e:
        logger.error(f"获取哈希表字段失败: {e}")
        raise HTTPException(status_code=500, detail=f"获取哈希表字段失败: {str(e)}")


@router.get("/hash/{name}", response_model=CacheResponse, summary="获取哈希表所有字段")
async def get_hash_all(
    name: str,
    redis: RedisManager = Depends(get_redis)
) -> CacheResponse:
    """获取哈希表所有字段"""
    try:
        data = await redis.hgetall(name)
        return CacheResponse(
            success=True,
            message="哈希表获取成功",
            data={"name": name, "fields": data}
        )
    except Exception as e:
        logger.error(f"获取哈希表失败: {e}")
        raise HTTPException(status_code=500, detail=f"获取哈希表失败: {str(e)}")